package com.example.demo.file;

import com.example.demo.entity.AccountBook;
import com.example.demo.service.IAccountBookService;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ThreadLocalRandom;

@RestController
@RequestMapping("file")
public class FileController {

    @Resource
    private IAccountBookService iAccountBookService;
    @PostMapping("upload")
    public void upload(MultipartFile file) throws IOException {
        AccountBook accountBook = new AccountBook();
        String originalFilename = file.getOriginalFilename();
        byte[] bytes = file.getBytes();
        accountBook.setHeadImg(bytes);
        accountBook.setFileName(originalFilename);
        accountBook.setFileSize(file.getSize());
        iAccountBookService.save(accountBook);

    }

    @GetMapping("download")
    public void download(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String id = request.getParameter("id");
        AccountBook accountBook = iAccountBookService.getById(Long.valueOf(id));
        if (accountBook != null){
            byte[] headImg = accountBook.getHeadImg();
            File file = new File("c://download");
            if (!file.exists()){
                file.mkdirs();
            }

            File filePath = new File("c://download//" + System.currentTimeMillis() + accountBook.getFileName());
            FileOutputStream outputStream = new FileOutputStream(filePath);
            outputStream.write(headImg);
            outputStream.flush();
            outputStream.close();
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            setAttachmentResponseHeader(response, accountBook.getFileName());
            writeBytes(filePath.getAbsolutePath(), response.getOutputStream());
            filePath.delete();
        }
    }


    private void writeBytes(String filePath, OutputStream os) throws IOException{
        FileInputStream fis = null;
        try
        {
            File file = new File(filePath);
            if (!file.exists())
            {
                throw new FileNotFoundException(filePath);
            }
            fis = new FileInputStream(file);
            byte[] b = new byte[1024];
            int length;
            while ((length = fis.read(b)) > 0)
            {
                os.write(b, 0, length);
            }
        }
        catch (IOException e)
        {
            throw e;
        }
        finally
        {
            if (os != null)
            {
                try
                {
                    os.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
            if (fis != null)
            {
                try
                {
                    fis.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
        }
    }

    private void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException{
        String percentEncodedFileName = percentEncode(realFileName);

        StringBuilder contentDispositionValue = new StringBuilder();
        contentDispositionValue.append("attachment; filename=")
                .append(percentEncodedFileName)
                .append(";")
                .append("filename*=")
                .append("utf-8''")
                .append(percentEncodedFileName);

        response.setHeader("Content-disposition", contentDispositionValue.toString());
    }

    private String percentEncode(String s) throws UnsupportedEncodingException{
        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
        return encode.replaceAll("\\+", "%20");
    }
}
